home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
djgpp
/
go32
/
fs
/
io.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-23
|
67KB
|
2,414 lines
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <pc.h>
#include <dos.h>
#include <keys.h>
#include <bios.h>
#include <sys/stat.h>
#include "ed.h"
#include "fsfuncts.h"
#include "io.h"
#include "serial.h"
#include "syms.h"
unsigned char screen_attr;
unsigned char screen_attr_normal;
unsigned char screen_attr_source;
unsigned char screen_attr_focus;
unsigned char screen_attr_ffocus;
unsigned char screen_attr_break;
unsigned char screen_attr_message;
unsigned char screen_attr_error;
unsigned char screen_attr_resize;
unsigned char screen_attr_asm;
unsigned char screen_attr_help;
unsigned char screen_attr_addr;
unsigned char screen_attr_hot;
unsigned char screen_attr_button;
unsigned char screen_attr_dfocus;
unsigned char st_ln_attr;
char *user_screen_save, *debug_screen_save;
char *read_buffer;
char StatusLine[100];
int cols, max_cols;
int rows, max_rows;
static int escaped = 0;
static int using_com_port_num;
static int first_transfer = 1;
static char *transfer_screen_save;
static char *my_line;
static char *small_line;
/* ---------------------------------------------------------------------- */
static unsigned int
get_com (void)
{
int ch;
do {
ch = com_rx();
} while (ch == 0);
return ch;
}
/* ---------------------------------------------------------------------- */
unsigned int
getykey (void)
{
if (using_com_port_num)
{ unsigned int ch, ch1, ch2;
if ((ch = escaped))
{ escaped = 0;
return (ch);
}
ch = get_com ();
switch (ch)
{ case 0x1b:
ch1 = get_com ();
if ((char)ch1 == '[')
{ ch2 = get_com ();
switch (ch2)
{ case 'A': /* ^[[A == Up */
return K_Up;
case 'B': /* ^[[B == Down */
return K_Down;
case 'C': /* ^[[C == Right */
return K_Right;
case 'D': /* ^[[D == Left */
return K_Left;
case 'H': /* ^[[H == Home */
return K_Home;
case 'K': /* ^[[K == End */
return K_End;
default:
escaped = ch1;
return (K_Escape);
}
} else
{ escaped = ch1;
return (K_Escape);
}
case 0x0d:
return K_Return;
default:
return ch;
}
} else
return getxkey();
}
/* ---------------------------------------------------------------------- */
static void
ansi_goto (int row, int col)
{
sprintf (small_line, "a[%d;%df", row + 1, col + 1);
small_line[0] = 27;
}
/* ---------------------------------------------------------------------- */
static void
ansi_color (int bg, int fg)
{
int is_bold = 0, is_blink = 0;
if (bg > 7)
{ is_blink = 1;
bg &= 7;
}
if (fg > 7)
{ is_bold = 1;
fg &= 7;
}
switch (bg)
{ case A_blue:
bg = A_red;
break;
case A_red:
bg = A_blue;
break;
case A_brown:
bg = A_cyan;
break;
case A_cyan:
bg = A_brown;
break;
}
switch (fg)
{ case A_blue:
fg = A_red;
break;
case A_red:
fg = A_blue;
break;
case A_brown:
fg = A_cyan;
break;
case A_cyan:
fg = A_brown;
break;
}
bg += 40;
fg += 30;
if (is_bold)
if (is_blink)
sprintf(small_line, "a[0;1;5;%d;%dm",bg,fg);
else
sprintf(small_line, "a[0;1;%d;%dm",bg,fg);
else
if (is_blink)
sprintf(small_line, "a[0;5;%d;%dm",bg,fg);
else
sprintf(small_line, "a[0;%d;%dm",bg,fg);
small_line[0] = 27;
}
/* ---------------------------------------------------------------------- */
static void
screen_goto (int row, int col)
{
ansi_goto (row, col);
com_txs (small_line);
}
/* ---------------------------------------------------------------------- */
void
screen_scroll (int lines)
{
int i;
screen_goto (rows, 0);
for (i = 0; i < lines; i++)
com_tx (10);
screen_goto (0, 0);
}
/* ---------------------------------------------------------------------- */
void
put (int x, int y, unsigned char *txt)
{
unsigned char *p
= (unsigned char *)(debug_screen_save + 3) + 2 * (max_cols * y + x);
while (*txt)
*p++ = *txt++,
*p++ = screen_attr;
}
/* ---------------------------------------------------------------------- */
void
putl (int x, int y, int l, unsigned char *txt)
{
unsigned char *p
= (unsigned char *)(debug_screen_save + 3) + 2 * (max_cols * y + x);
while (*txt && l > 0)
*p++ = *txt++,
*p++ = screen_attr,
l--;
while (l-- > 0)
*p++ = ' ',
*p++ = screen_attr;
}
/* ---------------------------------------------------------------------- */
void
clear_screen (void)
{
int l = rows * max_cols;
unsigned char *p
= (unsigned char *)(debug_screen_save + 3);
while (l-- > 0)
*p++ = ' ',
*p++ = screen_attr;
}
/* ---------------------------------------------------------------------- */
void
draw (int x, int y, unsigned char ch, int delta, int count)
{
short unsigned *p
= (short unsigned *)(debug_screen_save + 3) + (max_cols * y + x);
short unsigned attrch = ((unsigned)screen_attr << 8) + ch;
while (count--)
*p = attrch,
p += delta;
}
/* ---------------------------------------------------------------------- */
void
highlight (int x, int y, int len)
{
unsigned short *p
= (unsigned short *)(debug_screen_save + 4) + (max_cols * y + x);
while (len--)
*(unsigned char *)p = screen_attr,
p++;
}
/* ---------------------------------------------------------------------- */
void
frame (int x1, int y1, int x2, int y2, char *tittle)
{
if (!using_com_port_num)
{ draw (x1 + 1, y1, '─', 1, x2 - x1 - 1);
draw (x1 + 1, y2, '─', 1, x2 - x1 - 1);
draw (x1, y1 + 1, '│', max_cols, y2 - y1 - 1);
draw (x2, y1 + 1, '│', max_cols, y2 - y1 - 1);
put (x1, y1, "┌");
put (x2, y1, "┐");
put (x1, y2, "└");
put (x2, y2, "┘");
} else
{ draw (x1 + 1, y1, '-', 1, x2 - x1 - 1);
draw (x1 + 1, y2, '-', 1, x2 - x1 - 1);
draw (x1, y1 + 1, '|', max_cols, y2 - y1 - 1);
draw (x2, y1 + 1, '|', max_cols, y2 - y1 - 1);
put (x1, y1, "+");
put (x2, y1, "+");
put (x1, y2, "+");
put (x2, y2, "+");
}
if (tittle)
{ int t_start, t_end;
t_start = (x2 - x1 - 3 - strlen (tittle)) / 2;
if (t_start <= 2)
{ t_start = 2;
t_end = x2 - x1 - 3;
} else
t_end = t_start + strlen (tittle) + 1;
draw (x1 + t_start, y1, '>', 1 , 1);
putl (x1 + t_start + 1, y1, t_end - t_start - 1, tittle);
draw (x1 + t_end, y1, '<', 1, 1);
}
}
/* ---------------------------------------------------------------------- */
void
double_frame (int x1, int y1, int x2, int y2, char *tittle)
{
if (!using_com_port_num)
{ draw (x1 + 1, y1, '═', 1, x2 - x1 - 1);
draw (x1 + 1, y2, '═', 1, x2 - x1 - 1);
draw (x1, y1 + 1, '║', max_cols, y2 - y1 - 1);
draw (x2, y1 + 1, '║', max_cols, y2 - y1 - 1);
put (x1, y1, "╔");
put (x2, y1, "╗");
put (x1, y2, "╚");
put (x2, y2, "╝");
} else
{ draw (x1 + 1, y1, '=', 1, x2 - x1 - 1);
draw (x1 + 1, y2, '=', 1, x2 - x1 - 1);
draw (x1, y1 + 1, '[', max_cols, y2 - y1 - 1);
draw (x2, y1 + 1, ']', max_cols, y2 - y1 - 1);
put (x1, y1, "*");
put (x2, y1, "*");
put (x1, y2, "*");
put (x2, y2, "*");
}
if (tittle)
{ int t_start, t_end;
t_start = (x2 - x1 - 3 - strlen (tittle)) / 2;
if (t_start <= 2)
{ t_start = 2;
t_end = x2 - x1 - 3;
} else
t_end = t_start + strlen (tittle) + 1;
draw (x1 + t_start, y1, '>', 1 , 1);
putl (x1 + t_start + 1, y1, t_end - t_start - 1, tittle);
draw (x1 + t_end, y1, '<', 1, 1);
}
}
/* ---------------------------------------------------------------------- */
static void
get_line (char *screen, int line_num)
{
int i;
char *p2;
unsigned char *p =
(unsigned char *)(screen + 3) + 2 * max_cols * line_num;
p2 = my_line;
i = cols * 2;
while (i)
{
*p2++ = *p++;
i--;
}
*p2++ = 0;
}
/* ---------------------------------------------------------------------- */
static void
put_line (char *screen, char *full_line, int line_num)
{
unsigned char *p =
(unsigned char *)(screen + 3) + 2 * max_cols * line_num;
char *oneline = full_line;
int i = cols * 2;
while (i)
{
*p++ = *oneline++;
i--;
}
}
/* ---------------------------------------------------------------------- */
static void
get_differ (char *first_line, char *second_line)
{
char *line_one = first_line, *line_two = second_line;
char ch1_attr, ch1_ascii, ch2_attr, ch2_ascii;
int len, i = 0;
len = 1;
my_line[0] = '\0';
while (i < cols)
{ ch1_ascii = *line_one++;
ch1_attr = *line_one++;
ch2_ascii = *line_two++;
ch2_attr = *line_two++;
i++;
if ((ch1_ascii != ch2_ascii) || (ch1_attr != ch2_attr))
{ len += 5;
my_line[len - 6] = 255;
my_line[len - 5] = 255;
my_line[len - 4] = (unsigned char)i;
my_line[len - 3] = ch2_ascii;
my_line[len - 2] = ch2_attr;
my_line[len - 1] = '\0';
while (i < cols)
{ ch1_ascii = *line_one++;
ch1_attr = *line_one++;
ch2_ascii = *line_two++;
ch2_attr = *line_two++;
i++;
if ((ch1_ascii == ch2_ascii) && (ch1_attr == ch2_attr))
break;
len += 2;
my_line[len - 3] = ch2_ascii;
my_line[len - 2] = ch2_attr;
my_line[len - 1] = '\0';
}
}
}
}
/* ---------------------------------------------------------------------- */
static int
com_filter (int old_char)
{ old_char &= 0x7f;
switch (old_char)
{ case 27: /* ESC */
return 27;
case 30: /* Big Up Arrow */
return (int)('^');
case 31: /* Big Down Arrow */
return (int)('v');
case 127: /* DEL */
return (int)('.');
default:
return (old_char < 32) ? '.' : old_char;
}
}
/* ---------------------------------------------------------------------- */
static void
line_to_ansi (char *full_line, int line_num)
{
int i = cols, len;
unsigned char old_attr = 0, ch_attr, ch_ascii;
char *oneline = full_line;
ansi_goto (line_num, 0);
sprintf (my_line, small_line);
len = strlen (small_line);
while (i)
{ ch_ascii = *oneline++;
ch_attr = *oneline++;
if (old_attr != ch_attr)
{ old_attr = ch_attr;
ansi_color (ch_attr >> 4, ch_attr & 0x0f);
sprintf ((char *)(my_line + len), small_line);
len += strlen (small_line);
}
my_line[len] = com_filter (ch_ascii);
my_line[++len] = '\0';
i--;
}
}
/* ---------------------------------------------------------------------- */
static void
diff_to_ansi (unsigned char *diff_line, int line_num)
{
char *oneline = diff_line;
int i = 0, len = 0, dif_len = strlen(oneline);
char old_attr = 0, ch_attr = 0, ch_ascii = 0;
int is_pos = 0, pos = 0;
unsigned char char_one, char_two;
while (i < dif_len)
{ char_one = *oneline++;
char_two = *oneline++;
i += 2;
if ((char_one == 255) && (char_two == 255))
{ pos = *oneline;
if (pos <= cols)
{ i++;
oneline++;
is_pos = 1;
pos--;
}
else
{ ch_ascii = char_one;
ch_attr = char_two;
}
}
else
{ ch_ascii = char_one;
ch_attr = char_two;
}
if (is_pos)
{ ansi_goto (line_num, pos);
sprintf ((char *)(my_line + len), small_line);
len += strlen (small_line);
is_pos = 0;
}
else
{ if (old_attr != ch_attr)
{ old_attr = ch_attr;
ansi_color (ch_attr >> 4, ch_attr & 0x0f);
sprintf ((char *)(my_line + len), small_line);
len += strlen (small_line);
}
my_line[len] = com_filter(ch_ascii);
my_line[++len] = '\0';
}
}
}
/* ---------------------------------------------------------------------- */
static char new_line[1024] , old_line[1024];
static char diff_line[1024], ansi_line[1024];
/* ---------------------------------------------------------------------- */
static void
transfer_screen (char *screen)
{
int line_num;
if (first_transfer)
{ screen_scroll (rows);
line_num = 0;
do
{ get_line(screen, line_num);
put_line(transfer_screen_save, my_line, line_num);
strcpy (new_line, my_line);
line_to_ansi (new_line , line_num);
strcpy(ansi_line, my_line);
com_txs (ansi_line);
} while (++line_num < rows);
first_transfer = 0;
return;
}
line_num = 0;
do
{ get_line(screen, line_num);
strcpy(new_line, my_line);
get_line(transfer_screen_save, line_num);
strcpy(old_line, my_line);
if (strncmp (new_line, old_line, cols * 2))
{ put_line(transfer_screen_save, new_line, line_num);
get_differ (old_line, new_line);
strcpy(diff_line, my_line);
diff_to_ansi (diff_line, line_num);
strcpy(ansi_line, my_line);
line_to_ansi (new_line , line_num);
strcpy(diff_line, my_line);
if ((strlen (ansi_line) < strlen (diff_line)))
com_txs (ansi_line);
else
com_txs (diff_line);
}
line_num++;
} while (line_num < rows);
}
/* ---------------------------------------------------------------------- */
static void
recieve_screen (unsigned char *screen)
{
unsigned char *p2 = (unsigned char *)(screen + 3);
unsigned char *p = (unsigned char *)(transfer_screen_save + 3);
int i = max_rows * max_cols * 2;
while (i)
{
*p2++ = *p++;
i--;
}
}
/* ---------------------------------------------------------------------- */
void
put_screen (char *screen)
{
if (using_com_port_num)
transfer_screen(screen);
else
switch (*screen++)
{
case 0:
/* Text screen. */
ScreenSetCursor (screen[0], screen[1]);
ScreenUpdate (screen + 2);
break;
}
}
/* ---------------------------------------------------------------------- */
char *
get_screen ()
{
char *p;
int r, c;
p = malloc (max_cols * max_rows * 2 + 3); /* Was cols * rows * ... */
if (using_com_port_num)
{
if (transfer_screen_save)
recieve_screen (p);
else
for (r = 0; r < max_rows; r++)
for (c = 0; c < max_cols; c++)
{ p[2 * (r * max_cols + c) + 3] = ' ';
p[2 * (r * max_cols + c) + 4] = screen_attr;
}
}
else
{
ScreenGetCursor (&r, &c);
p[0] = 0;
p[1] = r;
p[2] = c;
ScreenRetrieve (p + 3);
}
return p;
}
/* ---------------------------------------------------------------------- */
char *
get_old_screen()
{
char *saved;
saved = debug_screen_save;
debug_screen_save = get_screen();
return saved;
}
/* ---------------------------------------------------------------------- */
void
restore_screen(char *saved)
{
free (debug_screen_save);
debug_screen_save = saved;
}
/* ---------------------------------------------------------------------- */
void
refresh()
{
put_screen (debug_screen_save);
}
/* ---------------------------------------------------------------------- */
/* Reportedly, `sleep' & `gettimeofday' are buggy under Dpmi -- emulate. */
int
mysleep (int secs)
{
struct time now;
unsigned now100, then100;
gettime (&now);
then100
= ((now.ti_hour * 60 + now.ti_min) * 60 + now.ti_sec + secs) * 100
+ now.ti_hund;
do
{
gettime (&now);
now100 = ((now.ti_hour * 60 + now.ti_min) * 60 + now.ti_sec) * 100
+ now.ti_hund;
if (now100 < 100)
break; /* Day turnover */
if (using_com_port_num)
{ if (get_com ())
break;
}
else
if (bioskey (1))
break;
}
while (now100 < then100);
return 0;
}
/* ---------------------------------------------------------------------- */
int
short_sleep (unsigned long msecs)
{
struct time now;
unsigned long now100, then100;
gettime (&now);
then100
= ((now.ti_hour * 60 + now.ti_min) * 60 + now.ti_sec) * 100
+ now.ti_hund + msecs;
do
{
gettime (&now);
now100 = ((now.ti_hour * 60 + now.ti_min) * 60 + now.ti_sec) * 100
+ now.ti_hund;
if (now100 < 100 || bioskey (1))
break; /* Day turnover */
}
while (now100 < then100);
if (bioskey(1))
return 1;
return 0;
}
/* ---------------------------------------------------------------------- */
/* Display a message in CLASS using FMT and ... as printf parameters.
The class determines the colour of the message and for how long time
it is displayed. */
void
message (CL_TYPE class, char *fmt, ...)
{ int space_len;
vsprintf (StatusLine, fmt, (&fmt) + 1);
space_len = (cols - strlen (StatusLine)) / 2;
sprintf (StatusLine, "%-50s", " ");
vsprintf (StatusLine + space_len, fmt, (&fmt) + 1);
switch (class)
{ case CL_Error:
st_ln_attr = screen_attr_error;
break;
default:
st_ln_attr = screen_attr_message;
}
redraw (0);
}
/* ---------------------------------------------------------------------- */
static int
input_string (int x, int y, int len, int *lastkey)
{ int key, esc = 0, pos, leave = 0;
int more_left = 0, insert_mode = 1, buf_len;
char *orig_str = strdup (read_buffer);
char *temp = alloca (4096);
pos = strlen (read_buffer);
do
{ draw (x, y, ' ', 1, len);
putl (x, y, len, read_buffer + more_left);
buf_len = strlen (read_buffer);
put_screen (debug_screen_save);
if (using_com_port_num)
screen_goto (y, x + pos);
else
ScreenSetCursor (y, x + pos);
if (*lastkey)
{ key = *lastkey;
*lastkey = 0;
} else
key = getykey ();
switch (key)
{ case K_Up:
case K_EUp:
case K_Down:
case K_EDown:
case K_Tab:
case K_BackTab:
case K_Control_N:
case K_Control_P:
*lastkey = key; /* Fall through */
case K_Return:
leave = 1;
esc = 0;
break;
case K_Escape:
key = getykey ();
if (key != K_Escape)
{ *lastkey = key; /* Wrong, reuse */
break;
} /* Else fall through */
case K_Control_G:
leave = 1;
esc = 1;
*lastkey = K_Control_G; /* So ESC ESC == C-g */
strcpy (read_buffer, orig_str);
break;
case K_Control_X:
key = getykey ();
switch (key)
{ case K_Control_O:
case K_Control_T:
insert_mode = !insert_mode;
break;
}
break;
case K_Insert:
case K_EInsert:
insert_mode = !insert_mode;
break;
case K_Delete:
case K_EDelete:
if (pos > 0 || more_left)
{ strcpy (temp, read_buffer + (pos + more_left) * sizeof (char));
if (pos + more_left == buf_len)
{ pos--;
read_buffer[pos + more_left] = '\0';
if (pos < 0)
{ pos++;
more_left--;
}
} else
{ strcpy (read_buffer + (pos + more_left - 1) * sizeof (char), temp);
if (more_left)
more_left--;
else
pos--;
}
}
break;
case K_Control_D:
if (pos + more_left < buf_len)
{ strcpy (temp, read_buffer + (pos + more_left + 1) * sizeof (char));
strcpy (read_buffer + (pos + more_left) * sizeof (char), temp);
}
break;
case K_Left:
case K_ELeft:
case K_Control_B:
if (more_left)
more_left--;
else if (pos)
pos--;
break;
case K_Right:
case K_ERight:
case K_Control_F:
if (pos + more_left < buf_len)
{ pos++;
if (pos == len)
{ more_left++;
pos--;
}
}
break;
default:
if (key >= ' ' && key <= 0xff)
{ if (insert_mode)
strcpy (temp, read_buffer + (pos + more_left) * sizeof (char));
read_buffer[pos + more_left] = key & 0xff;
pos++;
if (insert_mode)
strcpy (read_buffer + (pos + more_left) * sizeof (char), temp);
if (pos + more_left == buf_len)
read_buffer[buf_len] = '\0';
if (pos == len)
{ more_left++;
pos--;
}
}
}
} while (!leave);
put_screen (debug_screen_save);
return esc;
}
/* ---------------------------------------------------------------------- */
/* Read a string from the keyboard to `read_buffer'. The entry is started
with STARTTEXT. */
int
read_string (char *starttext)
{ char *save;
int result, temp;
strcpy (read_buffer, starttext);
save = debug_screen_save;
debug_screen_save = get_screen ();
screen_attr = screen_attr_focus;
put (0, rows - 1, "Input: ");
do
{ temp = 0;
result = input_string (7, rows - 1, cols - 7, &temp);
} while (temp && !result);
free (debug_screen_save);
debug_screen_save = save;
put_screen (debug_screen_save);
return (result);
}
/* ---------------------------------------------------------------------- */
int
my_read_string (char *prompt)
{ char *save;
int result, temp;
int prompt_len = strlen(prompt);
*read_buffer = '\0';
save = debug_screen_save;
debug_screen_save = get_screen ();
screen_attr = screen_attr_focus;
put (0, rows - 1, prompt);
do
{ temp = 0;
result = input_string (prompt_len, rows - 1, cols - prompt_len, &temp);
} while (temp && !result);
free (debug_screen_save);
debug_screen_save = save;
put_screen (debug_screen_save);
return (result);
}
/* ---------------------------------------------------------------------- */
int
my_get_char (char *prompt)
{ char *save, key[2];
int prompt_len = strlen(prompt);
save = debug_screen_save;
debug_screen_save = get_screen ();
screen_attr = screen_attr_focus;
key[1] = 0;
draw (0, rows - 1, ' ', 1, cols);
put (0, rows - 1, prompt);
put_screen (debug_screen_save);
if (using_com_port_num)
screen_goto (rows - 1, prompt_len);
else
ScreenSetCursor (rows - 1, prompt_len);
key[0] = getykey ();
put (prompt_len, rows - 1, key);
put_screen (debug_screen_save);
free (debug_screen_save);
debug_screen_save = save;
put_screen (debug_screen_save);
return key[0];
}
/* ---------------------------------------------------------------------- */
int /* 1 == y, 0 == n */
confirm (char *prompt)
{ int key = my_get_char (prompt);
if (key == 'y' || key == 'Y')
return (1);
return (0);
}
/* ---------------------------------------------------------------------- */
void
format_addr (char *output, char *input)
{ char *name;
int32 delta;
word32 addr;
int ok;
addr = parse_expression (4, input, &ok);
name = syms_val2name (addr, &delta);
if (name[0] != '0')
if (delta)
sprintf (output, "%s+%#lx", name, delta);
else
sprintf (output, "%s", name);
else
sprintf(output,"0x%08lx",addr);
strcpy (input, output);
}
/* ---------------------------------------------------------------------- */
void
format_word (char *output, char *input)
{ word32 temp = syms_name2val (input);
sprintf (output, "0x%08lx", temp);
strcpy (input, output);
}
/* ---------------------------------------------------------------------- */
void
format_deci (char *output, char *input)
{ word32 temp = syms_name2val (input);
sprintf (output, "%ld", temp);
strcpy (input, output);
}
/* ---------------------------------------------------------------------- */
void
format_int (char *output, char *input)
{ word32 temp = syms_name2val (input);
sprintf (output, "%ld", temp);
strcpy (input, output);
}
/* ---------------------------------------------------------------------- */
void
format_asis (char *output, char *input)
{ strcpy (output, input);
}
/* ---------------------------------------------------------------------- */
void
eval_word (void *output, char *input)
{ int ok;
word32 *out = (word32 *)output;
*out = parse_expression (4, input, &ok);
}
/* ---------------------------------------------------------------------- */
void
eval_asis (void *output, char *input)
{ char *temp = (char *)output;
strcpy (temp, input);
}
/* ---------------------------------------------------------------------- */
void
init_addr (char *output, char *input, word32 addr)
{ sprintf (input, "0x%08lx", *(word32 *)addr);
format_addr (output, input);
}
/* ---------------------------------------------------------------------- */
void
init_word (char *output, char *input, word32 addr)
{ sprintf (output, "0x%08lx", *(word32 *)addr);
strcpy (input, output);
}
/* ---------------------------------------------------------------------- */
void
init_deci (char *output, char *input, word32 addr)
{ sprintf (output, "%ld", *(word32 *)addr);
strcpy (input, output);
}
/* ---------------------------------------------------------------------- */
void
init_int (char *output, char *input, word32 addr)
{ sprintf (output, "%ld", *(long *)addr);
strcpy (input, output);
}
/* ---------------------------------------------------------------------- */
void
init_asis (char *output, char *input, word32 addr)
{ strcpy (output, (char *)addr);
strcpy (input, output);
}
/* ---------------------------------------------------------------------- */
int
editor (char *text, word32 addr, int x, int y, int len, int *key)
{ strcpy (read_buffer, text);
return (input_string (x, y, len, key));
}
/* ---------------------------------------------------------------------- */
int
action_done (DIALOG_ITEM dialog_data[])
{ return (1);
}
/* ---------------------------------------------------------------------- */
void
dialog (char *tittle,
DIALOG_ITEM dialog_data[], BUTTON_ITEM button_data[], int *ret)
{ char *save, **buffer, **inputs;
int key = 0, pos, leave = 0, editable = 0;
int x1 = 1, x2 = cols - x1 - 1;
int y1, y2, max_field_len = 0, max_button_len = 0;
int i, items, buttons, len = 0, x_button, width;
for (i = 0; dialog_data[i].field_name; i++)
{ len = strlen (dialog_data[i].field_name);
if (len > max_field_len)
max_field_len = len;
if (dialog_data[i].editable)
editable = 1;
}
width = x2 - x1 - max_field_len - 3;
items = i;
for (i = 0; button_data[i].name; i++)
{ len = strlen (button_data[i].name);
if (len > max_button_len)
max_button_len = len;
editable = 1;
}
buttons = i;
max_button_len += 2;
if (!editable)
{ *ret = 0;
return;
}
buffer = malloc (items * sizeof (char *));
inputs = malloc (items * sizeof (char *));
for (i = 0; i < items; i++)
{ if (dialog_data[i].input_length > width)
dialog_data[i].input_length = width;
buffer[i] = malloc (1024);
inputs[i] = malloc (1024);
dialog_data[i].initializer (buffer[i], inputs[i],
dialog_data[i].return_addr);
}
x_button = (cols / 2) - max_button_len * buttons / 2;
if (*ret >= items + buttons || *ret < 0)
*ret = 0;
pos = *ret;
while ((pos < items) && !(dialog_data[pos].editable))
{ pos++;
if (pos >= items + buttons)
pos = 0;
}
y1 = (rows / 2) - (items + 1) / 2 - 3;
y2 = rows - y1 - 1;
save = debug_screen_save;
debug_screen_save = get_screen ();
screen_attr = screen_attr_ffocus;
double_frame (x1, y1, x2, y2, tittle);
screen_attr = screen_attr_normal;
for (i = y1 + 1; i < y2; i++)
putl(x1 + 1, i, x2 - x1 - 2, " ");
for (i = 0; i < items; i++)
putl (x1 + 2, y1 + i + 2, max_field_len, dialog_data[i].field_name);
put_screen (debug_screen_save);
do
{ for (i = 0; i < items; i++)
{ screen_attr = (i == pos) ? screen_attr_dfocus : screen_attr_normal;
putl (x1 + max_field_len + 3, y1 + i + 2, dialog_data[i].input_length,
buffer[i]);
}
for (i = 0; i < buttons; i++)
{ screen_attr = (i + items == pos) ? screen_attr_dfocus
: screen_attr_button;
putl (x_button + i * max_button_len , y1 + items + 3,
max_button_len - 2, button_data[i].name);
}
put_screen (debug_screen_save);
if (pos < items)
{ if (!dialog_data[pos].editor (inputs[pos],
dialog_data[pos].return_addr,
x1 + max_field_len + 3,
y1 + pos + 2,
dialog_data[pos].input_length, &key))
{ dialog_data[pos].formatter (buffer[pos], read_buffer);
strcpy (inputs[pos], read_buffer);
dialog_data[pos].evaluater ((void *)dialog_data[pos].return_addr,
read_buffer);
if (!key)
key = K_Down;
} else
dialog_data[pos].initializer (buffer[pos], inputs[pos],
dialog_data[pos].return_addr);
screen_attr = screen_attr_dfocus;
putl (x1 + max_field_len + 3, y1 + pos + 2,
dialog_data[pos].input_length, buffer[pos]);
put_screen (debug_screen_save);
}
if (key == 0)
key = getykey();
switch(key)
{ case K_Up:
case K_EUp:
case K_BackTab:
case K_Control_P:
do
{ if (!pos)
pos = items + buttons - 1;
else
pos--;
} while ((pos < items) && !(dialog_data[pos].editable));
key = 0;
break;
case K_Down:
case K_EDown:
case K_Tab:
case K_Control_N:
do
{ pos++;
if (pos >= items + buttons)
pos = 0;
} while ((pos < items) && !(dialog_data[pos].editable));
key = 0;
break;
case K_Return:
if (pos >= items)
{ button_data[pos - items].action (dialog_data);
if (button_data[pos - items].stay)
for (i = 0; i < items; i++)
dialog_data[i].initializer (buffer[i], inputs[i],
dialog_data[i].return_addr);
else
{ *ret = pos - items + 1;
leave = 1;
}
key = 0;
screen_attr = screen_attr_ffocus;
double_frame (x1, y1, x2, y2, tittle);
screen_attr = screen_attr_normal;
for (i = y1 + 1; i < y2; i++)
putl(x1 + 1, i, x2 - x1 - 2, " ");
for (i = 0; i < items; i++)
putl (x1 + 2, y1 + i + 2, max_field_len, dialog_data[i].field_name);
}
break;
case K_Escape:
key = getykey ();
if (key != K_Escape)
break; /* Else fall through */
case K_Control_G:
leave = 1;
*ret = 0;
break;
default:
if (pos >= items)
key = 0;
break;
}
} while (!leave);
for (i = 0; i < items; i++)
{ free (buffer[i]);
free (inputs[i]);
}
free (buffer);
free (inputs);
free (debug_screen_save);
debug_screen_save = save;
}
/* ---------------------------------------------------------------------- */
char *
open_win(int width, int height, int attribute, int border,
int *x_start, int *y_start, int *actual_width, char *tittle)
{
char *saved;
int x1, y1, x2, y2;
saved = debug_screen_save;
debug_screen_save = get_screen();
x1 = cols / 2 - width / 2;
if (x1 < 1)
x1 = 1;
x2 = x1 + width;
if (x2 > cols - 1)
x2 = cols - 1;
y1 = rows / 2 - height / 2;
if (y1 < 1)
y1 = 1;
y2 = y1 + height;
if (y2 > rows - 1)
y2 = rows - 1;
screen_attr = attribute;
switch (border)
{
case 0:
case 1:
frame (x1 - 1, y1 - 1, x2, y2, tittle);
break;
case 2:
double_frame (x1 - 1, y1 - 1, x2, y2, tittle);
}
screen_attr = screen_attr_normal;
*x_start = x1;
*y_start = y1;
*actual_width = x2 - x1;
for (x2 = y1; x2 < y2; x2++)
putl (x1, x2, *actual_width, " ");
refresh ();
return saved;
}
/* ---------------------------------------------------------------------- */
void
close_win(char *saved)
{
free (debug_screen_save);
debug_screen_save = saved;
refresh ();
}
/* ---------------------------------------------------------------------- */
void
init_text (WIN_TEXT *text, char *tittle)
{
text->page = 0;
text->lines = 0;
if (tittle)
text->tittle = strdup (tittle);
else
text->tittle = 0;
}
/* ---------------------------------------------------------------------- */
void
add_text (WIN_TEXT *text, char *line)
{
char *p;
if (!line[0])
return;
p = strdup (line);
if (p)
{ text->lines++;
if (text->lines == 1)
text->page = malloc (sizeof (char *));
else
text->page = realloc (text->page, text->lines * sizeof (char *));
text->page[text->lines - 1] = p;
}
}
/* ---------------------------------------------------------------------- */
void
free_text (WIN_TEXT *text)
{
int i;
for (i = 0; i < text->lines; i++)
free (text->page[i]);
free (text->page);
free (text->tittle);
text->lines = 0;
text->page = 0;
text->tittle = 0;
}
/* ---------------------------------------------------------------------- */
void
text_win (WIN_TEXT text, int user_width, int user_height)
{
int x, y, i, width, height, not_done = 1, key, len;
int start_line = 0, pos = 0, textoffset = 0;
char *window_save;
if (user_height > rows - 1)
height = rows - 1;
else
height = user_height;
window_save = open_win (user_width, height, screen_attr_ffocus,
single_border, &x, &y, &width, text.tittle);
height -= 1;
while (not_done)
{
screen_attr = screen_attr_normal;
for (i = 0; i <= height; i++)
{
if (i + start_line < text.lines)
{ len = strlen (text.page[i + start_line]);
putl (x, y + i, width, text.page[i + start_line] +
((textoffset < len) ? textoffset : len));
} else
putl (x, y + i, width , " ");
}
screen_attr = screen_attr_focus;
len = strlen (text.page[pos + start_line]);
putl (x, y + pos, width, text.page[pos + start_line] +
((textoffset < len) ? textoffset : len));
refresh ();
key = getykey ();
if (key == K_Escape)
{ switch (key = getykey ())
{ case 'v':
case 'V':
key = K_PageUp;
break;
case '<':
key = K_Home;
break;
case '>':
key = K_End;
break;
case K_Escape:
key = K_Control_G;
break;
default:
key = 0;
break;
}
}
if (key == K_Control_X)
{ switch (key = getykey ())
{ case K_Control_W:
write_log (x, y, x + width, y + height);
break;
case '<':
textoffset++;
break;
case '>':
if (textoffset)
textoffset--;
break;
}
key = 0;
}
switch (key)
{
case K_Up:
case K_EUp:
case K_Left:
case K_ELeft:
case K_Control_P:
case K_Control_B:
if (pos == 0)
{ if (start_line)
start_line--;
}
else
pos--;
break;
case K_Down:
case K_EDown:
case K_Right:
case K_ERight:
case K_Control_N:
case K_Control_F:
if (pos < height)
{ if (start_line + pos < text.lines - 1)
pos++;
} else
{ if (start_line + pos < text.lines - 1)
start_line++;
}
break;
case K_PageUp:
case K_EPageUp:
if (start_line > height - 1)
start_line -= height - 1;
else
start_line = 0;
break;
case K_PageDown:
case K_EPageDown:
case K_Control_V:
if (start_line < text.lines - height - 1)
start_line += height - 1;
if (pos + start_line >= text.lines - 1)
pos = text.lines - start_line - 1;
break;
case K_Home:
case K_EHome:
start_line = 0;
pos = 0;
break;
case K_End:
case K_EEnd:
if (start_line + height < text.lines - 1)
{ start_line = text.lines - height - 1;
pos = text.lines - start_line - 1;
}
break;
case K_Return:
case K_Control_G:
not_done = 0;
}
}
close_win (window_save);
}
/* ---------------------------------------------------------------------- */
static void
seperate_hotkey (const char *s, char *s1, char *s2, char *s3)
{ int first, second, len;
len = strlen (s);
s1[0] = 0;
s2[0] = 0;
s3[0] = 0;
for (first = 0; (first < len) && (s[first] != '~'); first++)
;
if (s[first] != '~')
{ sprintf (s1, s);
return;
}
strncpy (s1, s, first);
s1[first] = 0;
for (second = first + 1; (second < len) && (s[second] != '~'); second++)
;
if (s[second] != '~')
{ sprintf (s2, s + first + 1);
return;
}
strncpy (s2, s + first + 1, second - first - 1);
s2[second - first - 1] = 0;
strcpy (s3, s + second + 1);
}
/* ---------------------------------------------------------------------- */
int
display_bar_menu (MENU_ITEM menu_data[], int *pos)
{ char *begin = alloca (cols), *mid = alloca (cols), *end = alloca (cols);
int i, len, l_begin, l_mid, l_end, x = 0;
for (i = 1; menu_data[i].name && x < cols; i++)
{ seperate_hotkey (menu_data[i].name, begin, mid, end);
l_begin = strlen (begin);
l_mid = strlen (mid);
l_end = strlen (end);
len = l_begin + l_mid + l_end + 2;
if (i == menu_data[0].type)
{
screen_attr = screen_attr_error;
putl (x, 0, 1, "*");
if (l_begin)
putl (x + 1, 0, l_begin, begin);
if (l_mid)
putl (x + 1 + l_begin, 0, l_mid, mid);
if (l_end)
putl (x + 1 + l_begin + l_mid, 0, l_end, end);
*pos = x;
}
else
{ screen_attr = screen_attr_normal;
putl (x, 0, 1, " ");
if (l_begin)
putl (x + 1, 0, l_begin, begin);
if (l_mid)
{ screen_attr = screen_attr_hot;
putl (x + 1 + l_begin, 0, l_mid, mid);
screen_attr = screen_attr_normal;
}
if (l_end)
putl (x + 1 + l_begin + l_mid, 0, l_end, end);
}
x += len + 1;
screen_attr = screen_attr_normal;
putl (x - 3, 0, 3, " ");
}
i--;
if (x < cols - 1)
putl (x, 0, cols - x, " ");
refresh ();
return i;
}
/* ---------------------------------------------------------------------- */
int
display_pop_menu (MENU_ITEM menu_data[], char *tittle, int x_pos, int y_pos)
{ char *begin = alloca (cols), *mid = alloca (cols), *end = alloca (cols);
int i, len, l_begin, l_mid, l_end;
int y = y_pos + 1, maxlen = 0;
for (i = 1; menu_data[i].name; i++)
{
len = strlen (menu_data[i].name) + 2;
if (len > maxlen)
maxlen = len;
}
maxlen -= 2;
for (i = 1; menu_data[i].name; i++)
{ seperate_hotkey (menu_data[i].name, begin, mid, end);
l_begin = strlen (begin);
l_mid = strlen (mid);
l_end = strlen (end);
len = l_begin + l_mid + l_end;
if (i == menu_data[0].type)
{ screen_attr = screen_attr_error;
putl (x_pos + 1, y, 1 , "*");
if (l_begin)
putl (x_pos + 2, y, l_begin, begin);
if (l_mid)
putl (x_pos + 2 + l_begin, y, l_mid, mid);
if (l_end)
putl (x_pos + 2 + l_begin + l_mid, y, l_end, end);
putl (x_pos + 2 + l_begin + l_mid + l_end, y, maxlen - len, " ");
} else
{ screen_attr = screen_attr_normal;
putl (x_pos + 1, y, 1 , " ");
if (l_begin)
putl (x_pos + 2, y, l_begin, begin);
if (l_mid)
{ screen_attr = screen_attr_hot;
putl (x_pos + 2 + l_begin, y, l_mid, mid);
screen_attr = screen_attr_normal;
}
if (l_end)
putl (x_pos + 2 + l_begin + l_mid, y, l_end, end);
putl (x_pos + 2 + l_begin + l_mid + l_end, y, maxlen - len, " ");
}
y++;
}
i--;
screen_attr = screen_attr_focus;
frame (x_pos, y_pos, x_pos + maxlen + 1, y, tittle);
screen_attr = screen_attr_normal;
refresh ();
return i;
}
/* ---------------------------------------------------------------------- */
static int
search_hotkey (MENU_ITEM menu_data[])
{ int i, len, maxlen = 0;
for (i = 1; menu_data[i].name; i++)
{ len = strlen (menu_data[i].hot_key);
if (len > maxlen)
maxlen = len;
}
len = strlen (read_buffer);
while (maxlen < len)
{ for (i = 0; i < len; i++)
read_buffer[i] = read_buffer[i + 1];
len--;
}
for (i = 1; menu_data[i].name; i++)
{ if (strcmp (read_buffer, menu_data[i].hot_key) == 0)
return (i);
}
return (0);
}
/* ---------------------------------------------------------------------- */
void
menu (MENU_ITEM menu_data[], int *BarSelect, int *PopSelect)
{ int buf_pos = 0;
int bar_item_num, pop_item_num;
int not_done, x, key = 0, lastkey = 0, downonce = 0;
char *save;
save = get_old_screen ();
read_buffer[buf_pos] = 0;
back_to_menu_bar:
not_done = 1;
bar_item_num = display_bar_menu (menu_data, &x);
while (not_done)
{ if (lastkey)
key = K_Return;
else if (key)
lastkey = 1;
else
key = getykey ();
switch (key)
{ case K_Left:
case K_ELeft:
case K_BackTab:
case K_Control_B:
buf_pos = 0;
menu_data[0].type--;
if (menu_data[0].type < 1)
menu_data[0].type = bar_item_num;
if (downonce)
{ lastkey = 1;
not_done = 0;
}
break;
case K_Right:
case K_ERight:
case K_Tab:
case K_Control_F:
buf_pos = 0;
menu_data[0].type++;
if (menu_data[0].type > bar_item_num)
menu_data[0].type = 1;
if (downonce)
{ lastkey = 1;
not_done = 0;
}
break;
case K_Down:
case K_EDown:
case K_Control_N:
case K_Control_P:
case K_Return:
not_done = 0;
break;
case K_Escape:
key = getykey ();
if (key != K_Escape)
{ read_buffer[buf_pos++] = K_Escape;
read_buffer[buf_pos++] = key;
read_buffer[buf_pos] = 0;
bar_item_num = search_hotkey (menu_data);
buf_pos = strlen (read_buffer);
if (bar_item_num)
{ menu_data[0].type = bar_item_num;
not_done = 0;
}
break;
} /* Else falls through */
case K_Control_G:
restore_screen (save);
refresh ();
*BarSelect = 0;
*PopSelect = 0;
return;
default:
read_buffer[buf_pos++] = key;
read_buffer[buf_pos] = 0;
bar_item_num = search_hotkey (menu_data);
buf_pos = strlen (read_buffer);
if (bar_item_num)
{ menu_data[0].type = bar_item_num;
not_done = 0;
}
break;
}
key = 0;
bar_item_num = display_bar_menu (menu_data, &x);
}
*BarSelect = menu_data[0].type;
if (menu_data[*BarSelect].type == ITEM_TYPE)
{ if (lastkey)
{ lastkey = 0;
goto back_to_menu_bar;
}
restore_screen (save);
refresh ();
return;
}
lastkey = 0;
downonce = 1;
not_done = 1;
buf_pos = 0;
while (not_done)
{ pop_item_num = display_pop_menu (menu_data[*BarSelect].child, 0, x, 1);
switch (key = getykey ())
{
case K_Up:
case K_EUp:
case K_Control_P:
buf_pos = 0;
menu_data[*BarSelect].child[0].type--;
if (menu_data[*BarSelect].child[0].type < 1)
menu_data[*BarSelect].child[0].type = pop_item_num;
break;
case K_Down:
case K_EDown:
case K_Control_N:
buf_pos = 0;
menu_data[*BarSelect].child[0].type++;
if (menu_data[*BarSelect].child[0].type > pop_item_num)
menu_data[*BarSelect].child[0].type = 1;
break;
case K_Return:
not_done = 0;
break;
case K_Escape:
key = getykey ();
if (key != K_Escape)
{ read_buffer[buf_pos++] = K_Escape;
read_buffer[buf_pos++] = key;
read_buffer[buf_pos] = 0;
pop_item_num = search_hotkey (menu_data[*BarSelect].child);
buf_pos = strlen (read_buffer);
if (pop_item_num)
{ menu_data[*BarSelect].child[0].type = pop_item_num;
not_done = 0;
}
break;
} /* Else falls through */
case K_Control_G:
restore_screen (save);
refresh ();
save = get_old_screen ();
key = 0;
downonce = 0;
goto back_to_menu_bar;
case K_Left:
case K_ELeft:
case K_Right:
case K_ERight:
case K_Tab:
case K_BackTab:
case K_Control_F:
case K_Control_B:
restore_screen (save);
refresh ();
save = get_old_screen ();
goto back_to_menu_bar;
default:
read_buffer[buf_pos++] = key;
read_buffer[buf_pos] = 0;
pop_item_num = search_hotkey (menu_data[*BarSelect].child);
buf_pos = strlen (read_buffer);
if (pop_item_num)
{ menu_data[*BarSelect].child[0].type = pop_item_num;
not_done = 0;
}
break;
}
}
*PopSelect = menu_data[*BarSelect].child[0].type;
restore_screen (save);
refresh ();
}
/* ---------------------------------------------------------------------- */
void
pop_menu (MENU_ITEM menu_data[], char *tittle, int x, int y, int *PopSelect)
{ int buf_pos = 0;
int pop_item_num;
int not_done;
char *save;
int key;
save = get_old_screen ();
read_buffer[buf_pos] = 0;
not_done = 1;
while (not_done)
{ pop_item_num = display_pop_menu (menu_data, tittle, x, y);
key = getykey ();
switch (key)
{ case K_Up:
case K_EUp:
case K_Control_P:
buf_pos = 0;
menu_data[0].type--;
if (menu_data[0].type < 1)
menu_data[0].type = pop_item_num;
break;
case K_Down:
case K_EDown:
case K_Control_N:
buf_pos = 0;
menu_data[0].type++;
if (menu_data[0].type > pop_item_num)
menu_data[0].type = 1;
break;
case K_Return:
not_done = 0;
break;
case K_Escape:
key = getykey ();
if (key != K_Escape)
{ read_buffer[buf_pos++] = K_Escape;
read_buffer[buf_pos++] = key;
read_buffer[buf_pos] = 0;
pop_item_num = search_hotkey (menu_data);
buf_pos = strlen (read_buffer);
if (pop_item_num)
{ menu_data[0].type = pop_item_num;
not_done = 0;
}
break;
} /* Else falls through */
case K_Control_G:
restore_screen (save);
refresh ();
*PopSelect = 0;
return;
default:
read_buffer[buf_pos++] = key;
read_buffer[buf_pos] = 0;
pop_item_num = search_hotkey (menu_data);
buf_pos = strlen (read_buffer);
if (pop_item_num)
{ menu_data[0].type = pop_item_num;
not_done = 0;
}
break;
}
}
*PopSelect = menu_data[0].type;
restore_screen (save);
refresh ();
}
/* ---------------------------------------------------------------------- */
void
show_menu_bar (MENU_ITEM menu_data[])
{ int old_menu_pos, temp_bar_sel;
old_menu_pos = menu_data[0].type;
menu_data[0].type = 0;
display_bar_menu (menu_data, &temp_bar_sel);
menu_data[0].type = old_menu_pos;
}
/* ---------------------------------------------------------------------- */
void
parse_string (PARSE_DEF definition[], char *s)
{ int i;
char sw[64], val[100];
while (1)
{ if (sscanf (s, "%s%n", sw, &i) < 1)
break;
s += i;
if (sscanf (s, "%s%n", val, &i) < 1)
break;
s += i;
for (i = 0; definition[i].sw; i++)
if (stricmp (sw, definition[i].sw) == 0)
{ if (definition[i].type == STR_TYPE)
strcpy (definition[i].val.s_val, val);
else
*(definition[i].val.i_val) = atol (val);
}
}
}
/* ---------------------------------------------------------------------- */
void
re_start_transfer ()
{ first_transfer = 1;
}
/* ---------------------------------------------------------------------- */
static char *filename = 0;
/* ---------------------------------------------------------------------- */
void
write_log (int x1, int y1, int x2, int y2)
{ unsigned char *p;
int r, c;
FILE *f;
struct stat statbuf;
p = (unsigned char *)(debug_screen_save + 3);
if (!filename)
if (my_read_string("Enter filename: "))
return;
else
filename = strdup(read_buffer);
if (stat(filename,&statbuf) != -1)
f = fopen(filename,"a+");
else
f = fopen(filename,"w+");
if (f)
{ char temp_ch;
struct date curr_date;
struct time curr_time;
getdate (&curr_date);
gettime (&curr_time);
for (r = 0; r < 20; r++)
fputc ('=', f);
sprintf (read_buffer, "%02d:%02d:%02d %02d/%02d/%04d ====\n",
curr_time.ti_hour, curr_time.ti_min, curr_time.ti_sec,
curr_date.da_mon, curr_date.da_day, curr_date.da_year);
fputs (read_buffer, f);
for (r = y1; r < y2; r++)
{ for (c = x1; c < x2; c++)
{ temp_ch = p[(r * cols + c) * 2];
switch (temp_ch)
{ case 10:
case 13:
case 26:
temp_ch = '.';
}
putc (temp_ch, f);
}
fputc ('\n', f);
}
fclose(f);
} else
{ message(CL_Error,"Cannot write to file %s",filename);
free (filename);
filename = 0;
}
}
/* ---------------------------------------------------------------------- */
static void /* Will use as much memory as needed, not nice. */
old_read_log (void)
{ FILE *f;
char *p;
int len;
WIN_TEXT read_text;
if (!filename)
if (my_read_string("Enter filename: "))
return;
else
filename = strdup(read_buffer);
f = fopen(filename,"r+");
if (f) /* File exist */
{ init_text (&read_text, filename);
p = malloc (max_cols + 5);
do
{ fgets (p, max_cols + 2, f);
len = strlen (p);
if (len)
{ if (p[len - 1] == 13 || p[len - 1] == 10)
p[len - 1] = 0;
}
len = feof (f);
if (!len)
add_text (&read_text, p);
} while (!len);
fclose (f);
free (p);
text_win (read_text, cols - 2, rows - 2);
free_text (&read_text);
} else
{ message(CL_Error,"Cannot open file %s",filename);
free (filename);
filename = 0;
}
}
/* ---------------------------------------------------------------------- */
#define TEXT_LEN 128
#define STRI_LEN 120
/* ---------------------------------------------------------------------- */
static FILE *
init_win_file (WIN_TEXT *text, char *fname, int lines, int *f_pos)
{ FILE *f;
int i, pos, fpos, not_eof, read_bytes, left;
char *p, *temp = alloca (TEXT_LEN);
f = fopen (fname, "rb");
if (!f)
return (f);
*f_pos = 0;
i = 0;
pos = 0;
fpos = 0;
do
{ fseek (f, fpos, SEEK_SET);
read_bytes = fread (read_buffer, 1, 4096, f);
not_eof = (read_bytes == 4096) ? 1 : 0;
p = read_buffer;
left = read_bytes;
while (1)
{ for (pos = 0; pos < left && p[pos] != 0x0a; pos++)
;
if (pos == left)
break;
p[pos] = 0;
if (pos > 0 && p[pos - 1] == 0x0d)
p[pos - 1] = 0;
strcpy (temp, p);
p += pos + 1;
left -= pos + 1;
pos--;
for (; pos < TEXT_LEN; pos++)
temp[pos] = ' ';
temp[pos - 1] = 0;
add_text (text, temp);
i++;
if (i == lines)
break;
}
fpos += read_bytes - left;
} while (not_eof && i < lines);
return (f);
}
/* ---------------------------------------------------------------------- */
static int
read_win_file (WIN_TEXT *text, FILE *f, int d_lines, int *f_pos)
{ int pos, fpos, bytes_to_read, bytes_read, lines, i, left;
char *p;
if (d_lines < 0)
{ if (*f_pos == 0)
return (0);
lines = 0;
d_lines *= -1;
do
{ fpos = *f_pos - 4096;
if (fpos < 0)
fpos = 0;
bytes_to_read = *f_pos - fpos;
fseek (f, fpos, SEEK_SET);
bytes_read = fread (read_buffer, 1, bytes_to_read, f);
if (bytes_read != bytes_to_read)
{ message (CL_Error, "Error reading file.");
return (0);
}
for (pos = bytes_read - 1; pos > 0 && lines < d_lines; pos--)
if (read_buffer[pos] == 0x0a)
{ lines++;
*f_pos = fpos + pos - 1;
if (*f_pos < 0)
*f_pos = 0;
}
if (fpos == 0 && lines < d_lines)
{ lines++;
*f_pos = 0;
}
} while (lines < d_lines && fpos > 0);
for (pos = text->lines - 1; pos >= lines; pos--)
strcpy (text->page[pos], text->page[pos - lines]);
fpos = *f_pos;
pos = 0;
do
{ fseek (f, fpos, SEEK_SET);
bytes_read = fread (read_buffer, 1, 4096, f);
p = read_buffer;
left = bytes_read;
while (1)
{ for (i = 0; i < left && p[i] != 0x0a; i++)
;
if (i == left)
break;
p[i] = 0;
if (i > 0 && p[i - 1] == 0x0d)
p[i - 1] = 0;
strncpy (text->page[pos], p, STRI_LEN);
p += i + 1;
left -= i + 1;
pos++;
if (pos == lines)
break;
}
fpos += bytes_read - left;
} while (pos < lines && bytes_read == 4096);
return (lines);
}
else
{ int start_f_pos;
lines = 0;
fpos = *f_pos;
left = text->lines;
bytes_read = 4096;
while (lines < text->lines && bytes_read == 4096)
{ fseek (f, fpos, SEEK_SET);
bytes_read = fread (read_buffer, 1, 4096, f);
i = fpos;
for (pos = 0; pos < bytes_read && lines < text->lines; pos++)
if (read_buffer[pos] == 0x0a)
{ lines++;
if (left > 0)
{ left--;
*f_pos = i + pos + 1;
}
fpos = i + pos + 1;
}
}
start_f_pos = fpos;
bytes_read = 4096;
lines = 0;
while (lines < d_lines && bytes_read == 4096)
{ fseek (f, fpos, SEEK_SET);
bytes_read = fread (read_buffer, 1, 4096, f);
p = read_buffer;
i = fpos;
for (pos = 0; pos < bytes_read && lines < d_lines; pos++)
if (read_buffer[pos] == 0x0a)
{ lines++;
fpos = i + pos + 1;
}
}
for (pos = 0; pos + lines < text->lines; pos++)
strcpy (text->page[pos], text->page[pos + lines]);
fpos = start_f_pos;
pos = text->lines - lines;
do
{ fseek (f, fpos, SEEK_SET);
bytes_read = fread (read_buffer, 1, 4096, f);
p = read_buffer;
left = bytes_read;
while (1)
{ for (i = 0; i < left && p[i] != 0x0a; i++)
;
if (i == left)
break;
p[i] = 0;
if (i > 0 && p[i - 1] == 0x0d)
p[i - 1] = 0;
strncpy (text->page[pos], p, STRI_LEN);
p += i + 1;
left -= i + 1;
pos++;
if (pos == text->lines)
break;
}
fpos += bytes_read - left;
} while (pos < text->lines && bytes_read == 4096);
return (lines);
}
return (0);
}
/* ---------------------------------------------------------------------- */
static int
file_win (char *fname, int user_width, int user_height)
{ WIN_TEXT text;
int x, y, i, width, height, not_done = 1, key, len;
int start_line = 0, pos = 0, textoffset = 0;
char *window_save;
int cache_lines, read_lines, file_pos;
FILE *f;
if (user_height > rows - 1)
height = rows - 1;
else
height = user_height;
init_text (&text, fname);
window_save = open_win (user_width, height, screen_attr_ffocus,
single_border, &x, &y, &width, text.tittle);
height -= 1;
cache_lines = height * 2;
f = init_win_file (&text, fname, height * 3, &file_pos);
if (!f)
return (0);
while (not_done)
{
screen_attr = screen_attr_normal;
for (i = 0; i <= height; i++)
{
if (i + start_line < text.lines)
{ len = strlen (text.page[i + start_line]);
putl (x, y + i, width, text.page[i + start_line] +
((textoffset < len) ? textoffset : len));
} else
putl (x, y + i, width , " ");
}
screen_attr = screen_attr_focus;
len = strlen (text.page[pos + start_line]);
putl (x, y + pos, width, text.page[pos + start_line] +
((textoffset < len) ? textoffset : len));
refresh ();
key = getykey ();
if (key == K_Escape)
{ switch (key = getykey ())
{ case 'v':
case 'V':
key = K_PageUp;
break;
case '<':
key = K_Home;
break;
case '>':
key = K_End;
break;
case K_Escape:
key = K_Control_G;
break;
default:
key = 0;
break;
}
}
if (key == K_Control_X)
{ switch (key = getykey ())
{ case K_Control_W:
write_log (x, y, x + width, y + height);
break;
case '<':
textoffset++;
break;
case '>':
if (textoffset)
textoffset--;
break;
}
key = 0;
}
switch (key)
{
case K_Up:
case K_EUp:
case K_Left:
case K_ELeft:
case K_Control_P:
case K_Control_B:
if (pos == 0)
{ if (start_line)
start_line--;
else
{ read_lines = read_win_file (&text, f, -cache_lines, &file_pos);
if (read_lines)
start_line += read_lines - 1;
}
}
else
pos--;
break;
case K_Down:
case K_EDown:
case K_Right:
case K_ERight:
case K_Control_N:
case K_Control_F:
if (pos < height)
{ if (start_line + pos < text.lines - 1)
pos++;
else
{ read_lines = read_win_file (&text, f, cache_lines, &file_pos);
if (read_lines)
{ start_line -= read_lines - 1;
pos++;
}
}
} else
{ if (start_line + pos < text.lines - 1)
start_line++;
else
{ read_lines = read_win_file (&text, f, cache_lines, &file_pos);
if (read_lines)
start_line -= read_lines - 1;
}
}
break;
case K_PageUp:
case K_EPageUp:
if (start_line <= height - 1)
{ read_lines = read_win_file (&text, f, -cache_lines, &file_pos);
if (read_lines)
start_line += read_lines;
}
if (start_line > height - 1)
start_line -= height - 1;
else
start_line = 0;
break;
case K_PageDown:
case K_EPageDown:
case K_Control_V:
if (start_line >= text.lines - height - 1)
{ read_lines = read_win_file (&text, f, cache_lines, &file_pos);
if (read_lines)
start_line -= read_lines;
}
if (start_line < text.lines - height - 1)
start_line += height - 1;
if (start_line >= text.lines - height - 1)
{ read_lines = read_win_file (&text, f, cache_lines, &file_pos);
if (read_lines)
start_line -= read_lines;
}
if (pos + start_line >= text.lines - 1)
pos = text.lines - start_line - 1;
break;
case K_Home:
case K_EHome:
start_line = 0;
pos = 0;
break;
case K_End:
case K_EEnd:
if (start_line + height < text.lines - 1)
{ start_line = text.lines - height - 1;
pos = text.lines - start_line - 1;
}
break;
case K_Return:
case K_Control_G:
not_done = 0;
}
}
close_win (window_save);
free_text (&text);
fclose (f);
return (1);
}
/* ---------------------------------------------------------------------- */
void
read_log ()
{ if (0 == 1) /* Or memory == oo */
{ old_read_log ();
return;
}
if (!filename)
if (my_read_string("Enter filename: "))
return;
else
filename = strdup(read_buffer);
if (!file_win (filename, cols - 2, rows - 2))
{ message(CL_Error,"Cannot open file %s",filename);
free (filename);
filename = 0;
}
}
/* ---------------------------------------------------------------------- */
void
read_write_log (int x1, int y1, int x2, int y2)
{ int key = my_get_char ("Read or write? (r/w): ");
if ((key == 'W') || (key == 'w'))
{ if (!filename)
if (my_read_string("Enter filename: "))
return;
else
filename = strdup(read_buffer);
else
if (!read_string (filename))
{ free (filename);
filename = strdup (read_buffer);
}
write_log (x1, y1, x2, y2);
} else
{ if (!filename)
if (my_read_string("Enter filename: "))
return;
else
filename = strdup(read_buffer);
else
if (!read_string (filename))
{ free (filename);
filename = strdup (read_buffer);
}
read_log ();
}
}
/* ---------------------------------------------------------------------- */
void
init_color (int color)
{ if (color)
{ screen_attr_normal = (A_grey << 4) + A_blue;
screen_attr_source = (A_grey << 4) + A_black;
screen_attr_focus = (A_blue << 4) + A_white;
screen_attr_ffocus = (A_cyan << 4) + A_white;
screen_attr_break = (A_red << 4) + A_white;
screen_attr_message = (A_green << 4) + A_white;
screen_attr_error = (A_red << 4) + A_white;
screen_attr_resize = (A_grey << 4) + A_green;
screen_attr_asm = (A_grey << 4) + A_brown;
screen_attr_help = (A_grey << 4) + A_yellow;
screen_attr_addr = (A_grey << 4) + A_bold + A_black;
screen_attr_hot = (A_grey << 4) + A_red;
screen_attr_button = (A_green << 4) + A_black;
screen_attr_dfocus = (A_green << 4) + A_yellow;
} else
{ screen_attr_normal = (A_black << 4) + A_grey;
screen_attr_source = screen_attr_normal;
screen_attr_focus = (A_grey << 4) + A_black;
screen_attr_ffocus = (A_grey << 4) + A_black;
screen_attr_break = (A_black << 4) + A_white;
screen_attr_message = (A_grey << 4) + A_white;
screen_attr_error = (A_grey << 4) + A_black;
screen_attr_resize = (A_grey << 4) + A_black;
screen_attr_asm = screen_attr_normal;
screen_attr_help = screen_attr_normal;
screen_attr_addr = screen_attr_normal;
screen_attr_hot = screen_attr_break;
screen_attr_button = screen_attr_normal;
screen_attr_dfocus = screen_attr_focus;
}
st_ln_attr = screen_attr_message;
}
/* ---------------------------------------------------------------------- */
void
init_io (int com_port)
{ int screen_mode;
using_com_port_num = com_port;
my_line = malloc (4096);
small_line = malloc (40);
max_cols = 80;
max_rows = 50;
if (using_com_port_num)
{
cols = 80;
rows = 24;
com_init (using_com_port_num);
screen_mode = 3;
}
else
{ screen_mode = ScreenMode ();
max_cols = ScreenCols ();
max_rows = ScreenRows ();
cols = max_cols;
rows = max_rows;
}
if (cols < 80 || rows < 24)
{
fprintf (stderr, "\nDebugger error:\n\
There are only %d columns and %d rows\n\
in this display mode.\n\
The debugger needs at least\n\
80 columns and 24 rows.\n",
cols, rows);
exit (1);
}
read_buffer = malloc (4096);
transfer_screen_save = 0;
transfer_screen_save = get_screen ();
transfer_screen_save[1] = transfer_screen_save[2] = 0;
switch (screen_mode)
{
case 2:
case 7:
/* Mono */
init_color (0);
break;
default:
/* Colour */
init_color (1);
}
}
/* ---------------------------------------------------------------------- */
void
re_init_io (int com_port, int new_rows, int new_cols)
{
cols = new_cols;
rows = new_rows;
if (using_com_port_num)
com_done();
if (com_port)
{ using_com_port_num = com_port;
com_init(using_com_port_num);
first_transfer = 1;
if (cols > max_cols)
cols = max_cols;
if (rows > max_rows)
rows = max_rows;
}
free (transfer_screen_save);
transfer_screen_save = 0;
transfer_screen_save = get_screen ();
transfer_screen_save[1] = transfer_screen_save[2] = 0;
first_transfer = 1;
}
/* ---------------------------------------------------------------------- */